package zheezes.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author hcconquer@gmail.com
 */
public class ZRegex {
	public final static int PATTERN_IPADDR = 1;
	
	private final static Map<Integer, Pattern> PATTERNS = new HashMap<Integer, Pattern>();
	
	private List<Pattern> pats = new ArrayList<Pattern>();

	static {
		PATTERNS.put(PATTERN_IPADDR, Pattern.compile(
				"(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)" +
				"(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}"
				));
	}
	
	public static String[] matches(Pattern pattern, String input, int max) {
		if (pattern == null) {
			return null;
		}
		List<String> list = new ArrayList<String>();
		Matcher m = pattern.matcher(input);
		while (m.find()) {
			list.add(m.group());
			if (list.size() >= max) {
				break;
			}
		}
		return list.toArray(new String[0]);
	}
	
	public static String match(Pattern pattern, String input, int index) {
		String[] ms = matches(pattern, input, index + 1);
		if (ms == null || ms.length <= index) {
			return null;
		}
		return ms[index];
	}
	
	public static String match(Pattern pattern, String input) {
		return match(pattern, input, 0);
	}
	
	public static int matchCount(Pattern pattern, String input, int max) {
		if (pattern == null) {
			return -1;
		}
		Matcher m = pattern.matcher(input);
		int count = 0;
		while (m.find()) {
			count++;
			if (count >= max) {
				break;
			}
		}
		return count;
	}
	
	public static boolean matchCount(Pattern pattern, String input) {
		return matchCount(pattern, input, 1) > 0;
	}
	
	public static Pattern pattern(int pat) {
		return PATTERNS.get(pat);
	}

	public static int match(int pat, String input, int max) {
		Pattern p = PATTERNS.get(pat);
		if (p == null) {
			return -1;
		}
		Matcher m = p.matcher(input);
		int count = 0;
		while (m.find()) {
			count++;
			if (count >= max) {
				break;
			}
		}
		return count;
	}
	
	public static boolean match(int pat, String input) {
		return match(pat, input, 1) > 0;
	}

	public int add(String p) {
		return pats.add(Pattern.compile(p)) ? 0 : -1;
	}

	public int add(String[] ps) {
		if (ps == null) {
			return -1;
		}
		List<Pattern> tp = new ArrayList<Pattern>();
		for (String p : ps) {
			if (!tp.add(Pattern.compile(p))) {
				return -1;
			}
		}
		return pats.addAll(tp) ? 0 : -1;
	}

	public boolean match(String str) {
		if (str == null) {
			return false;
		}
		for (Pattern p : pats) {
			Matcher match = p.matcher(str);
			if (!match.find()) {
				// System.out.printf("%s  ---   %s\n", str, p.pattern());
				return false;
			}
		}
		return true;
	}

	public static void main(String[] args) {
		ZRegex regex = new ZRegex();
		new ZRegex();
		regex.add(new String[] { "[a-z]+", "[A-Z]+", "[0-9]+", "[@#*=]+",
				"[^\\s]{6,10}" });
		String[] us = new String[] { "1234@a", "ABC3a#@", "1Ac@", "ABC 3a#@" };
		for (String s : us) {
			if (regex.match(s)) {
				System.out.println("PASS");
			} else {
				System.out.println("FAIL");
			}
		}
	}
}
